package com.petecat.interchan.base.warning.rule.service.impl;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.mhuang.common.util.DataUtils;
import com.petecat.interchan.base.warning.empl.entity.BsWarningEmpl;
import com.petecat.interchan.base.warning.empl.service.IWarningEmplService;
import com.petecat.interchan.base.warning.rule.entity.BsWarningRule;
import com.petecat.interchan.base.warning.rule.mapper.IWarningRuleMapper;
import com.petecat.interchan.base.warning.rule.service.IWarningRuleService;
import com.petecat.interchan.core.exception.BusinessException;
import com.petecat.interchan.core.service.impl.BaseServiceImpl;
import com.petecat.interchan.protocol.Result;
import com.petecat.interchan.protocol.base.empl.dto.BsWarningEmplQryDTO;
import com.petecat.interchan.protocol.base.rule.dto.BsWarningRuleAddDTO;
import com.petecat.interchan.protocol.base.rule.dto.BsWarningRuleQryDTO;
import com.petecat.interchan.protocol.base.rule.vo.BsWarningRuleQryVO;
import com.petecat.interchan.protocol.base.rule.vo.BsWarningRuleTreeVO;
import com.petecat.interchan.protocol.data.Page;
import com.petecat.interchan.protocol.data.PageVO;
import com.petecat.interchan.protocol.sso.sysuser.SysUserAddDTO;
import com.petecat.interchan.redis.IdWorker;
import com.petecat.interchan.redis.commands.IRedisExtCommands;

@Service
public class WarningRuleServiceImpl extends BaseServiceImpl<BsWarningRule, String> implements IWarningRuleService {

	@Autowired
	private IWarningRuleMapper ruleMapper;

	@Autowired
	private IWarningEmplService warningEmplService;

	@Autowired
	private IRedisExtCommands redisExtCommands;

	@Autowired
	private Environment environment;

	private final static String SYUSER_REDIS_USERID_TO_USER_PREKEY = "syur_user_uid_";

	private final static Integer ZERO = 0;

	private final static String BS_EWARNING = "bs_ewarning";

	private final static Logger logger = LoggerFactory.getLogger(WarningRuleServiceImpl.class);

	@Override
	public PageVO<BsWarningRuleQryVO> queryWarningRuleByPage(BsWarningRuleQryDTO BsWarningRuleQryDTO) {
		SysUserAddDTO sysUserAddDTO = redisExtCommands.hget(SYUSER_REDIS_USERID_TO_USER_PREKEY,
				BsWarningRuleQryDTO.getUserId(), SysUserAddDTO.class);
		if (null == sysUserAddDTO) {
			throw new BusinessException(Result.SYS_RESULT_FAILD, environment.getProperty("user_not_exites"));
		}
		String user = "0".equals(sysUserAddDTO.getIsMaster()) ? sysUserAddDTO.getUserid() : null;
		BsWarningRuleQryDTO.setUserId(user);
		BsWarningRule BsWarningRule = DataUtils.copyTo(BsWarningRuleQryDTO, BsWarningRule.class);
		int count = this.ruleMapper.count(BsWarningRule);
		PageVO<BsWarningRuleQryVO> pageVo = new PageVO<>();
		if (count > 0) {
			Page<BsWarningRule> page = new Page<>();
			page.setRows(BsWarningRuleQryDTO.getRows());
			page.setStart(BsWarningRuleQryDTO.getStart());
			page.setRecord(BsWarningRule);
			List<BsWarningRule> companyList = this.ruleMapper.page(page);
			pageVo.setResult(DataUtils.copyTo(companyList, BsWarningRuleQryVO.class));
		}
		pageVo.setTotalSize(count);
		return pageVo;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveWarningRule(List<BsWarningRuleAddDTO> bsWarningRuleAddDTO, String userId, String token, String status) {
		List<BsWarningRule> config = DataUtils.copyTo(bsWarningRuleAddDTO, BsWarningRule.class);
		int i = 0;
		for (BsWarningRule bsWarningRule : config) {
			bsWarningRule.setCreateTime(new Date());
			bsWarningRule.setOperatorTime(new Date());
			bsWarningRule.setId(String.valueOf(new IdWorker().nextId()));
			bsWarningRule.setOperaorUserId(userId);
			bsWarningRule.setUserId(userId);
			bsWarningRule.setStatus("1");
			this.ruleMapper.save(bsWarningRule);
			// 添加人员
			List<BsWarningEmplQryDTO> warningEmplList = bsWarningRuleAddDTO.get(i).getWarningEmplList();
			List<BsWarningEmpl> empl = DataUtils.copyTo(warningEmplList, BsWarningEmpl.class);
			for (BsWarningEmpl s : empl) {
				s.setRuleId(bsWarningRule.getId());
				warningEmplService.save(s);
			}
			// 获取到第N个规则的人员信息
			i++;
			// 通过userId去获取预警人员信息 缓存里
			List<BsWarningEmplQryDTO> qryVo = DataUtils.copyTo(empl, BsWarningEmplQryDTO.class);
			qryVo.parallelStream().forEach(e -> {
				String hget = redisExtCommands.hget(ZERO, "sys_company_user", e.getUserId());
				JSONObject json = JSONObject.parseObject(hget);
				e.setUserName(json.getString("name"));
				e.setSms(json.getString("sms"));
				e.setEmail(json.getString("email"));
			});
			// 存规则
			try {
				redisExtCommands.hset(ZERO, "sys_company_" + token + "_user", bsWarningRule.getId(), qryVo);
			} catch (Exception e) {
				logger.error("saveWarningRule 将预警规则存进Redis失败,预警规则配置为：{}", warningEmplList, e);
			}
		}
		// 存入预警信息 key:token value:规则列表 :config
		if("1".equals(status)) {
			try {
				redisExtCommands.hset(ZERO, BS_EWARNING, token, config);
			} catch (Exception e) {
				logger.error("saveWarningRule 将预警配置存进Redis失败,预警配置为：{}", config, e);
			}
		}
	}

	/**
	 * 查詢Tree 規則
	 */
	@Override
	public PageVO<BsWarningRuleTreeVO> queryWarningRuleTree(BsWarningRuleQryDTO bsWarningConfigQryDTO) {
		SysUserAddDTO sysUserAddDTO = redisExtCommands.hget(SYUSER_REDIS_USERID_TO_USER_PREKEY,
				bsWarningConfigQryDTO.getUserId(), SysUserAddDTO.class);
		if (null == sysUserAddDTO) {
			throw new BusinessException(Result.SYS_RESULT_FAILD, environment.getProperty("user_not_exites"));
		}
		String user = "0".equals(sysUserAddDTO.getIsMaster()) ? sysUserAddDTO.getUserid() : null;
		bsWarningConfigQryDTO.setUserId(user);
		List<BsWarningRuleTreeVO> treeVO = this.ruleMapper.queryWarningRuleTree(bsWarningConfigQryDTO);
		PageVO<BsWarningRuleTreeVO> page = new PageVO<BsWarningRuleTreeVO>();
		if (!treeVO.isEmpty()) {
			page.setResult(treeVO);
		}
		return page;
	}

	/**
	 * 通过配置id获取规则
	 */
	@Override
	public List<BsWarningRule> queryWarningListById(String configId) {
		List<BsWarningRule> list = this.ruleMapper.queryWarningListById(configId);
		if (!list.isEmpty()) {
			return list;
		}
		return null;
	}

	/**
	 * 通过规则IDS删除规则
	 */
	@Override
	public void deleteRuleById(String[] ruleId) {
		this.ruleMapper.deleteRuleById(ruleId);
	}

}
